package estore2;

import estore.model.Product;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class EStoreClient {
    private static final String SERVER_HOST = "localhost";
    private static final int SERVER_PORT = 8888;
    private final Scanner scanner = new Scanner(System.in);
    private String userRole;
    private final Map<String, Integer> shoppingCart = new HashMap<>(); // 本地购物车存储
    private Socket clientSocket; // 复用连接，避免重复登录
    private ObjectInputStream ois;
    private ObjectOutputStream oos;

    public static void main(String[] args) {
        new EStoreClient().start();
    }

    public void start() {
        try {
            if (!login()) {
                System.out.println("登录失败，退出");
                return;
            }
            while (true) {
                showMenu();
                int choice = scanner.nextInt();
                scanner.nextLine();
                switch (choice) {
                    case 1:
                        browseProducts();
                        break;
                    case 2:
                        addToCart();
                        break;
                    case 3:
                        viewCart();
                        break;
                    case 4:
                        showSortedProducts();
                        break;
                    case 5:
                        if ("admin".equals(userRole)) {
                            updateStock();
                        } else {
                            System.out.println("权限不足");
                        }
                        break;
                    case 6:
                        if ("admin".equals(userRole)) {
                            addProduct();
                        } else {
                            System.out.println("权限不足");
                        }
                        break;
                    case 0:
                        logout();
                        return;
                    default:
                        System.out.println("无效选项");
                }
            }
        } catch (Exception e) {
            System.err.println("程序异常：" + e.getMessage());
        } finally {
            scanner.close();
            closeConnection();
        }
    }

    private boolean login() throws Exception {
        System.out.println("\n--- 用户登录 ---");
        System.out.print("用户名：");
        String username = scanner.nextLine();
        System.out.print("密码：");
        String password = scanner.nextLine();
        clientSocket = new Socket(SERVER_HOST, SERVER_PORT);
        oos = new ObjectOutputStream(clientSocket.getOutputStream());
        ois = new ObjectInputStream(clientSocket.getInputStream());
        Map<String, String> loginMap = new HashMap<>();
        loginMap.put("username", username);
        loginMap.put("password", password);
        oos.writeObject(loginMap);
        String response = (String) ois.readObject();
        if (response.startsWith("SUCCESS")) {
            userRole = response.split(":")[1];
            System.out.println("登录成功，角色：" + (userRole.equals("admin") ? "管理员" : "客户"));
            return true;
        } else {
            System.out.println(response);
            closeConnection();
            return false;
        }
    }

    private void showMenu() {
        System.out.println("\n ----欢迎来到C/S架构商城---- ");
        System.out.println("1. 浏览所有商品");
        System.out.println("2. 添加商品到购物车");
        System.out.println("3. 查看购物车");
        System.out.println("4. 自定义排序浏览商品");
        if ("admin".equals(userRole)) {
            System.out.println("5. 更新商品库存");
            System.out.println("6. 添加新商品");
        }
        System.out.println("0. 退出");
        System.out.print("请输入选择: ");
    }

    private void browseProducts() throws Exception {
        oos.writeObject("GET_ALL_PRODUCTS");
        List<Product> products = (List<Product>) ois.readObject();
        System.out.println("\n--- 商品列表 ---");
        if (products.isEmpty()) {
            System.out.println("无商品");
            return;
        }
        products.forEach(System.out::println);
    }

    private void addToCart() throws Exception {
        System.out.print("商品ID：");
        String productId = scanner.nextLine();
        System.out.print("购买数量：");
        int quantity = scanner.nextInt();
        scanner.nextLine();
        if (quantity <= 0) {
            System.out.println("数量必须为正数");
            return;
        }
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("action", "ADD_TO_CART");
        requestMap.put("productId", productId);
        requestMap.put("quantity", quantity);
        oos.writeObject(requestMap);
        String response = (String) ois.readObject();
        if (response.startsWith("SUCCESS")) {
            System.out.println(response);
            shoppingCart.put(productId, shoppingCart.getOrDefault(productId, 0) + quantity);
        } else {
            System.err.println(response);
        }
    }

    private void viewCart() {
        System.out.println("\n--- 我的购物车 ---");
        if (shoppingCart.isEmpty()) {
            System.out.println("购物车为空");
            return;
        }
        double total = 0.0;
        for (Map.Entry<String, Integer> entry : shoppingCart.entrySet()) {
            try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT);
                 ObjectOutputStream tempOos = new ObjectOutputStream(socket.getOutputStream());
                 ObjectInputStream tempOis = new ObjectInputStream(socket.getInputStream())) {
                tempOos.writeObject("GET_ALL_PRODUCTS");
                List<Product> products = (List<Product>) tempOis.readObject();
                Product product = products.stream()
                        .filter(p -> p.getId().equals(entry.getKey()))
                        .findFirst().orElse(null);
                if (product != null) {
                    double subtotal = product.getPrice() * entry.getValue();
                    System.out.printf("商品：%-20s | 单价：¥%-8.2f | 数量：%-3d | 小计：¥%.2f\n",
                            product.getName(), product.getPrice(), entry.getValue(), subtotal);
                    total += subtotal;
                }
            } catch (Exception e) {
                System.err.println("获取商品信息失败：" + e.getMessage());
            }
        }
        System.out.printf("总计：¥%.2f\n", total);
    }

    private void showSortedProducts() throws Exception {
        System.out.println("\n--- 排序方式 ---");
        System.out.println("1. 价格从低到高");
        System.out.println("2. 价格从高到低");
        System.out.println("3. 库存从多到少");
        System.out.print("选择：");
        int sortType = scanner.nextInt();
        scanner.nextLine();
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("action", "SORT_PRODUCTS");
        requestMap.put("sortType", sortType);
        oos.writeObject(requestMap);
        List<Product> sortedProducts = (List<Product>) ois.readObject();
        System.out.println("\n--- 排序后商品列表 ---");
        sortedProducts.forEach(System.out::println);
    }

    private void updateStock() throws Exception {
        System.out.print("商品ID：");
        String productId = scanner.nextLine();
        System.out.print("新库存：");
        int newStock = scanner.nextInt();
        scanner.nextLine();
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("action", "UPDATE_STOCK");
        requestMap.put("productId", productId);
        requestMap.put("newStock", newStock);
        oos.writeObject(requestMap);
        System.out.println(ois.readObject());
    }

    private void addProduct() throws Exception {
        System.out.print("商品ID：");
        String id = scanner.nextLine();
        System.out.print("商品名称：");
        String name = scanner.nextLine();
        System.out.print("商品价格：");
        double price = scanner.nextDouble();
        System.out.print("商品库存：");
        int stock = scanner.nextInt();
        scanner.nextLine();
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("action", "ADD_PRODUCT");
        requestMap.put("id", id);
        requestMap.put("name", name);
        requestMap.put("price", price);
        requestMap.put("stock", stock);
        oos.writeObject(requestMap);
        System.out.println(ois.readObject());
    }

    private void logout() throws Exception {
        oos.writeObject("LOGOUT");
        System.out.println(ois.readObject());
        closeConnection();
    }

    private void closeConnection() {
        try {
            if (ois != null) ois.close();
            if (oos != null) oos.close();
            if (clientSocket != null) clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}